package com.songtech.server.netty;

import com.songtech.server.netty.Initializer.ServerInitializer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import net.sf.ehcache.util.NamedThreadFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.net.InetSocketAddress;
import java.nio.channels.spi.SelectorProvider;
import java.util.concurrent.ThreadFactory;

/**
 * Create By YINN on 2018/4/3 16:06
 * Description :
 */

//@Component
public class Server {

    private final int port;  //端口号

    public Server(int port) {
        this.port = port;
    }

    @Autowired
    private ServerInitializer serverInitializer;   //处理链

    //    @PostConstruct
    public void start() throws Exception {

        serverStart();

    }

    /**
     * Created by YINN on 2018/4/6 18:32.
     *
     * @Description : 启动服务
     * @Result :
     */
    public void serverStart() throws Exception {

////        EventLoopGroup group = new NioEventLoopGroup();
//        EventLoopGroup bossGroup = new NioEventLoopGroup();
//        EventLoopGroup workerGroup = new NioEventLoopGroup();

        //netty的线程池模型设置成主从线程池模式，这样可以应对高并发请求
        //当然netty还支持单线程、多线程网络IO模型，可以根据业务需求灵活配置
        ThreadFactory threadRpcFactory = new NamedThreadFactory("NettyRPC ThreadFactory");

        //方法返回到Java虚拟机的可用的处理器数量
        int parallel = Runtime.getRuntime().availableProcessors() * 2;

        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup(parallel,threadRpcFactory, SelectorProvider.provider());

        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .localAddress(new InetSocketAddress(port))
                    .childHandler(serverInitializer)
                    .option(ChannelOption.SO_SNDBUF, 1024 * 32)
                    .option(ChannelOption.SO_SNDBUF, 1024 * 32)
                    .option(ChannelOption.SO_KEEPALIVE, true)
                    .option(ChannelOption.SO_BACKLOG, 511);

            ChannelFuture f = b.bind().sync();
            f.channel().closeFuture().sync();

        } finally {
            bossGroup.shutdownGracefully().sync();
            workerGroup.shutdownGracefully().sync();
        }
    }
}
